package com.zhiwen.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.zhiwen.common.api.PageResult;
import com.zhiwen.common.api.Result;
import com.zhiwen.domain.entity.Notification;
import com.zhiwen.service.NotificationProducer;
import com.zhiwen.service.NotificationService;
import com.zhiwen.service.UserService;
import com.zhiwen.domain.vo.NotificationVO;
import com.zhiwen.domain.vo.UserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 通知控制器
 */
@Tag(name = "通知管理", description = "通知相关接口")
@RestController
@RequestMapping("/notifications")
@Validated
public class NotificationController {

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private UserService userService;

    @Autowired
    private NotificationProducer notificationProducer;

    /**
     * 获取当前用户的未读通知数
     */
    @SaCheckLogin
    @GetMapping("/unread/count")
    @Operation(summary = "获取未读通知数", description = "获取当前登录用户的未读通知数量")
    public Result<Long> getUnreadCount() {
        Long userId = StpUtil.getLoginIdAsLong();
        Long count = notificationService.getUnreadCount(userId);
        return Result.success(count);
    }

    /**
     * 获取当前用户的通知列表
     */
    @SaCheckLogin
    @GetMapping()
    @Operation(summary = "获取通知列表", description = "分页获取当前登录用户的通知列表，支持按已读状态筛选")
    public Result<PageResult<NotificationVO>> getNotificationList(
            @Parameter(description = "已读状态：0-未读，1-已读，不传则查询全部") @RequestParam(required = false) Integer isRead,
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer pageSize) {

        Long userId = StpUtil.getLoginIdAsLong();
        PageResult<Notification> pageResult = notificationService.getUserNotifications(userId, isRead, pageNum, pageSize);

        // 转换为VO对象
        List<NotificationVO> voList = new ArrayList<>();
        if (pageResult.getRecords() != null && !pageResult.getRecords().isEmpty()) {
            // 获取所有发送者ID
            List<Long> senderIds = pageResult.getRecords().stream()
                    .map(Notification::getSenderId)
                    .filter(id -> id != null)
                    .distinct()
                    .collect(Collectors.toList());

            // 批量获取发送者信息
            Map<Long, UserVO> userMap = userService.getUserVOMap(senderIds);

            // 构建VO列表
            for (Notification notification : pageResult.getRecords()) {
                NotificationVO vo = new NotificationVO(notification);
                if (notification.getSenderId() != null) {
                    vo.setSender(userMap.get(notification.getSenderId()));
                }
                voList.add(vo);
            }
        }

        // 构建VO分页结果
        PageResult<NotificationVO> voPageResult = new PageResult<>();
        voPageResult.setRecords(voList);
        voPageResult.setTotal(pageResult.getTotal());
        voPageResult.setPages(pageResult.getPages());
        voPageResult.setPageNum(pageResult.getPageNum());
        voPageResult.setPageSize(pageResult.getPageSize());
        voPageResult.setHasNext(pageResult.isHasNext());
        voPageResult.setHasPrevious(pageResult.isHasPrevious());

        return Result.success(voPageResult);
    }

    /**
     * 标记通知为已读
     */
    @SaCheckLogin
    @PutMapping("/{id}/read")
    @Operation(summary = "标记通知为已读", description = "将指定通知标记为已读状态")
    public Result<Boolean> markAsRead(@Parameter(description = "通知ID") @PathVariable("id") Long notificationId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean success = notificationService.markAsRead(notificationId, userId);
        return Result.success(success);
    }

    /**
     * 标记所有通知为已读
     */
    @SaCheckLogin
    @PutMapping("/read/all")
    @Operation(summary = "标记所有通知为已读", description = "将当前用户所有未读通知标记为已读")
    public Result<Boolean> markAllAsRead() {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean success = notificationService.markAllAsRead(userId);
        return Result.success(success);
    }

    /**
     * 删除通知
     */
    @SaCheckLogin
    @DeleteMapping("/{id}")
    @Operation(summary = "删除通知", description = "删除指定的通知")
    public Result<Boolean> deleteNotification(@Parameter(description = "通知ID") @PathVariable("id") Long notificationId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean success = notificationService.deleteNotification(notificationId, userId);
        return Result.success(success);
    }

    /**
     * 系统发送通知（仅管理员可用）
     */
    @SaCheckLogin
    @PostMapping("/system/send")
    @Operation(summary = "发送系统通知", description = "管理员发送系统通知，可以发给指定用户或所有用户")
    public Result<Boolean> sendSystemNotification(
            @Parameter(description = "通知标题") @RequestParam String title,
            @Parameter(description = "通知内容") @RequestParam String content,
            @Parameter(description = "接收者ID（为空则发送给所有用户）") @RequestParam(required = false) Long receiverId) {

        // 检查权限（只有管理员可以发送系统通知）
        if (!StpUtil.hasRole("admin")) {
            return Result.fail("权限不足，只有管理员可以发送系统通知");
        }

        try {
            // 使用RabbitMQ通知生产者发送通知
            notificationProducer.sendSystemNotification(title, content, receiverId);
            return Result.success(true);
        } catch (Exception e) {
            return Result.fail("发送系统通知失败：" + e.getMessage());
        }
    }

    /**
     * 批量发送系统通知（仅管理员可用）
     */
    @SaCheckLogin
    @PostMapping("/system/batch-send")
    @Operation(summary = "批量发送系统通知", description = "管理员批量发送系统通知给多个指定用户")
    public Result<Boolean> sendSystemNotificationBatch(
            @Parameter(description = "通知标题") @RequestParam String title,
            @Parameter(description = "通知内容") @RequestParam String content,
            @Parameter(description = "接收者ID列表") @RequestParam List<Long> receiverIds) {

        // 检查权限（只有管理员可以发送系统通知）
        if (!StpUtil.hasRole("admin")) {
            return Result.fail("权限不足，只有管理员可以发送系统通知");
        }

        try {
            // 使用RabbitMQ通知生产者发送批量通知
            notificationProducer.sendSystemNotificationToMultiUsers(title, content, receiverIds);
            return Result.success(true);
        } catch (Exception e) {
            return Result.fail("批量发送系统通知失败：" + e.getMessage());
        }
    }
}
